package com.wu.client.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.wu.client.constant.FansTypeEnum;
import com.wu.client.constant.RedisKeyConstant;
import com.wu.client.constant.ResTypeEnum;
import com.wu.client.dao.redis.Likes;
import com.wu.client.service.UserLikesService;
import com.wu.client.vo.req.FavoritesReq;
import com.wu.client.vo.res.song.SongResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@RequiredArgsConstructor
public class UserLikesServiceImpl  implements UserLikesService {
    private final StringRedisTemplate stringRedisTemplate;
    @Override
    public void likesAndUnlike(FavoritesReq favoritesReq) {
        Integer type = ResTypeEnum.getCodeByType(favoritesReq.getContentType());
        String contentId = favoritesReq.getContentId();

        String userId = favoritesReq.getUserId().toString();
        String likesRedisKey = RedisKeyConstant.getLikesRedisKey(type, contentId);
        String userLikesRedisKey = RedisKeyConstant.getUserLikesRedisKey(type, favoritesReq.getUserId());

        if (Boolean.TRUE.equals(favoritesReq.getAction())) {
            stringRedisTemplate.opsForSet().add(likesRedisKey, userId);
            stringRedisTemplate.opsForSet().add(userLikesRedisKey, contentId);
        }else {
            stringRedisTemplate.opsForSet().remove(likesRedisKey,userId);
            stringRedisTemplate.opsForSet().remove(userLikesRedisKey, contentId);
        }
    }



    @Override
    public <T> Map<T, Likes> checkUserIfLike(ResTypeEnum typeEnum, Long userId, List<T> resIds) {
        if (resIds.isEmpty()) {
            return Collections.emptyMap();  // 如果用户ID为null或者资源ID为空，直接返回空Map
        }
        Map<T, Likes> existMap = new HashMap<>(resIds.size());
        // 处理 pipeline 返回结果
        List<Object> results = stringRedisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            if (ObjectUtil.isNotNull(userId)){
                for (T resId : resIds) {
                    String redisKey = RedisKeyConstant.getLikesRedisKey(typeEnum.getCode(), resId);
                    connection.sIsMember(redisKey.getBytes(), userId.toString().getBytes());
                    connection.sCard(redisKey.getBytes());
                }
            }else {
                for (T resId : resIds) {
                    String redisKey = RedisKeyConstant.getLikesRedisKey(typeEnum.getCode(), resId);
                    connection.sCard(redisKey.getBytes());
                }
            }

            return null;
        });
        if (ObjectUtil.isNotNull(userId)){
            for (int i = 0; i < resIds.size(); i++) {
                Boolean member = (Boolean) results.get(i * 2); // sIsMember 结果
                Long size = (Long) results.get(i * 2 + 1); // sCard 结果
                existMap.put(resIds.get(i), new Likes(size,member));
            }
        }else {
            for (int i = 0; i < resIds.size(); i++) {
                Long size = (Long) results.get(i); // sCard 结果
                existMap.put(resIds.get(i), new Likes(size,false));
            }
        }
        return existMap;
    }

    @Override
    public <T> Map<T, Likes> checkUserIfFans(FansTypeEnum typeEnum, Long userId, List<T> resIds) {
        if (resIds.isEmpty()) {
            return Collections.emptyMap();  // 如果用户ID为null或者资源ID为空，直接返回空Map
        }
        Map<T, Likes> existMap = new HashMap<>(resIds.size());
        // 处理 pipeline 返回结果
        List<Object> results = stringRedisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            if (ObjectUtil.isNotNull(userId)){
                for (T resId : resIds) {
                    String redisKey = RedisKeyConstant.getFansRedisKey(typeEnum.getCode(), resId);
                    connection.sIsMember(redisKey.getBytes(), userId.toString().getBytes());
                    connection.sCard(redisKey.getBytes());
                }
            }else {
                for (T resId : resIds) {
                    String redisKey = RedisKeyConstant.getLikesRedisKey(typeEnum.getCode(), resId);
                    connection.sCard(redisKey.getBytes());
                }
            }

            return null;
        });
        if (ObjectUtil.isNotNull(userId)){
            for (int i = 0; i < resIds.size(); i++) {
                Boolean member = (Boolean) results.get(i * 2); // sIsMember 结果
                Long size = (Long) results.get(i * 2 + 1); // sCard 结果
                existMap.put(resIds.get(i), new Likes(size,member));
            }
        }else {
            for (int i = 0; i < resIds.size(); i++) {
                Long size = (Long) results.get(i); // sCard 结果
                existMap.put(resIds.get(i), new Likes(size,false));
            }
        }
        return existMap;
    }




}
